#include "protocolparse.h"
#include <string>
#include <iostream>
#include <memory>

#define parse_log(fmt, ...)  printf("[PARSE]:" fmt, ##__VA_ARGS__)

ProtocolParse::ProtocolParse()
{
//    m_img_path = "";
//    m_xml_path = "";
    m_res_path = "";
}

/**
 * create inter obj
 */
int ProtocolParse::create(QString res_path)
{
//    m_img_path = img_path;
//    m_xml_path = xml_path;
    m_res_path = res_path;

    return 0;
}

// run task
void *ProtocolParse::routine(void *arg)
{
    (void)(arg);
    return NULL;
}

/// 设置发送回调
void ProtocolParse::set_send_data_cb(FSendBufCb buf_cb, void *buf_ctx)
{
    snd_buf_cb      = buf_cb;
    snd_buf_cb_ctx  = buf_ctx;
}

void ProtocolParse::set_parse_file_cb(FShowXml cb, void *cb_context)
{
    show_cb = cb;
    show_cb_context = cb_context;
}

void ProtocolParse::set_protocol(int ptl)
{
    protocol = ptl;
}

/// data income from link
void ProtocolParse::data_in(void *data, int data_len, uint32_t ip, uint16_t port, uint64_t time)
{

    rmt_ip      = ip;
    rmt_port    = port;
    cur_time    = time;

    parse_data(data, data_len, NULL);
}


void ProtocolParse::data_in_from_unix(void *data, int data_len, uint64_t time, ProtocolData* ptr_parse)
{
    (void)time;
    parse_data(data, data_len, ptr_parse);
}

//// parse income data
void ProtocolParse::parse_data(void *data, int data_len, ProtocolData* ptr_parse)
{
    (void)data_len;
    if (!ptr_parse)
        return;
    std::string jsonStr = (char *)data;

    bool res;
    JSONCPP_STRING errs;
    Json::Value root;
    Json::CharReaderBuilder readerBuilder;
    std::unique_ptr<Json::CharReader> const jsonReader(readerBuilder.newCharReader());
    res = jsonReader->parse(jsonStr.c_str(), jsonStr.c_str()+jsonStr.length(), &root, &errs);

    if (!res || !errs.empty())
    {
         parse_log("parse json error, errs:%s\n", errs.c_str());
    }

    Json::Value::Members members;
    members = root.getMemberNames();

    if (CheckJsonValueType(root, "ui_type", Json::stringValue))
    {
         ptr_parse->ui_type = QString::fromStdString(root["ui_type"].asString());
    }
    if (CheckJsonValueType(root, "suffix", Json::stringValue))
    {
         ptr_parse->suffix = QString::fromStdString(root["suffix"].asString());
    }
    if (CheckJsonValueType(root, "file_path", Json::stringValue))
    {
        ptr_parse->file_path = QString::fromStdString(root["file_path"].asString());
    }

    if (CheckJsonValueType(root, "start_id", Json::intValue))
    {
         ptr_parse->start_id = root["start_id"].asInt();
    }
    if (CheckJsonValueType(root, "stop_id", Json::intValue))
    {
        ptr_parse->stop_id = root["stop_id"].asInt();
    }

    if(CheckJsonValueType(root, "curr_or_next_id", Json::intValue))
    {
         ptr_parse->curr_or_next_id = root["curr_or_next_id"].asInt();
    }

    if (CheckJsonValueType(root, "car_number", Json::intValue))
    {
        ptr_parse->car_number = root["car_number"].asInt();
    }
    if (CheckJsonValueType(root, "key_position", Json::intValue))
    {
        ptr_parse->key_position = root["key_position"].asInt();
    }
    if (CheckJsonValueType(root, "door_status", Json::intValue))
    {
        ptr_parse->door_status = root["door_status"].asInt();
    }

    if (CheckJsonValueType(root, "skip_list", Json::arrayValue))
    {
        ptr_parse->skip_list.clear();
        for (unsigned int i = 0; i < root["skip_list"].size(); i++)
        {
             parse_log("skip_list:%d\n", root["skip_list"][i].asInt());
             ptr_parse->skip_list.push_back(root["skip_list"][i].asInt());
        }
    }
    if (CheckJsonValueType(root, "eta_list", Json::arrayValue))
    {
        ptr_parse->eta_list.clear();
        for (unsigned int i = 0; i < root["eta_list"].size(); i++)
        {
             ptr_parse->eta_list.push_back(root["eta_list"][i].asInt());
        }
    }
    if (CheckJsonValueType(root, "scroll_msg", Json::stringValue))
    {
        ptr_parse->scroll_msg = QString::fromStdString(root["scroll_msg"].asString());
    }

    if (CheckJsonValueType(root, "emergency_img", Json::stringValue))
    {
        ptr_parse->emergency_img = QString::fromStdString(root["emergency_img"].asString());
    }

    if (CheckJsonValueType(root, "emergency_texts", Json::arrayValue))
    {
        const Json::Value arrayObj = root["emergency_texts"];
        for (unsigned i = 0; i < arrayObj.size(); i++)
        {
            struct emergenry_list list;
            LOG_QDEBUG<<__func__<<QString::fromStdString(arrayObj[i]["id"].asString());

            parse_log("text:%s\n", arrayObj[i]["text"].asString().c_str());

            LOG_QDEBUG<<__func__<<QString::fromLocal8Bit(arrayObj[i]["text"].asString().data());
            list.id = QString::fromStdString( arrayObj[i]["id"].asString());
            list.text = QString::fromLocal8Bit(arrayObj[i]["text"].asString().data());
            ptr_parse->emergency_text.push_back(list);
        }
    }

    if (CheckJsonValueType(root, "route", Json::stringValue))
    {
        ptr_parse->route = QString::fromStdString(root["route"].asString());
    }

    if (CheckJsonValueType(root, "items_change", Json::objectValue))
    {
        const Json::Value changeObj = root["items_change"];

        Json::Value::Members subMembers;
        subMembers = changeObj.getMemberNames();

        for (std::vector<std::string>::iterator it = subMembers.begin(); it != subMembers.end(); ++it)
        {
            if (CheckJsonValueType(changeObj, *it, Json::objectValue))
            {
                const Json::Value itemObj = changeObj[*it];

                change_property item;

                if (CheckJsonValueType(itemObj, "x", Json::intValue))
                {
                    item.x = itemObj["x"].asInt();
                }
                if (CheckJsonValueType(itemObj, "y", Json::intValue))
                {
                    item.y = itemObj["y"].asInt();
                }
                if (CheckJsonValueType(itemObj, "w", Json::intValue))
                {
                    item.w = itemObj["w"].asInt();
                }
                if (CheckJsonValueType(itemObj, "h", Json::intValue))
                {
                    item.h = itemObj["h"].asInt();
                }
                if (CheckJsonValueType(itemObj, "content", Json::stringValue))
                {
                    item.content = QString::fromStdString(itemObj["content"].asString());
                }
                ptr_parse->items_change[QString::fromStdString(*it)] = item;
            }
        }
    }

    show_cb(show_cb_context,  ptr_parse->file_path);

    return;
}


int ProtocolParse::send_data(void *context, void *buf, int len, uint32_t ip, uint16_t port)
{
    int ret;
    ret = snd_buf_cb(snd_buf_cb_ctx, context, buf, len, ip, port, cur_time);
    if (ret < 0)
    {

    }

    return ret;
}
